iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0

前言

在將近兩週的時間,透過不斷反覆開發 Lambda FunctionAPI Gateway 綁定的作業後,也完成上傳影片、刪除影片、字幕產生、轉檔等功能後,開始要讓除了我以外的人來使用了。 現在我們遇到一個問題,那便是先前註冊帳號時,只吃兩樣數值,「帳號」和「密碼」。 一旦使用者註冊完後忘記密碼,就必須直接找我來進行重設密碼,那很蠻煩的欸。

需求

  1. 改變註冊時需要多拿 「信箱 email」
  2. 註冊完成後,發一封信給使用者,讓他按下確認後,才算成功啟用,這邊需要透過 API Gateway 進行認證
  3. 當使用者忘記密碼時,發一封信重設密碼連結的信給使用者
  4. 透過連結可以開啟重設密碼頁面
  5. 所以還需要一個欄位來記錄是否為 「啟用 is_varified」

DynamoDB 結構設計

Users 表(主檔)

  1. PK: username (String)
  2. GSI1: GSI1 → PartitionKey: email(用來檢查信箱唯一性 & 以信找人)
  3. 欄位:
    • username (S)
    • email (S)
    • password_hash (S)
    • password_salt (S)
    • is_verified (BOOL, 預設 false)
    • created_at (S, ISO8601)

AuthTokens 表(一次性 Token)

  1. PK: token (String, 使用 UUID v4)
  2. 欄位:
    • token_type (S) → VERIFY 或 RESET
    • username (S)
    • email (S)
    • expires_at (N, epoch seconds) ← DynamoDB TTL 指向這個欄位
    • used (BOOL, 預設 false)
    • created_at (S, ISO8601)

為什麼分兩張?

  • Users 是穩定資料;
    AuthTokens 是短命一次性資料,TTL 自動清理最方便。

API 與流程圖

路由一覽(API Gateway → Lambda)

  • POST /register:註冊(輸入 username, email, password)→ 建 Users(is_verified=false),產 VERIFY token,寄驗證信
  • GET /verify?token=...:點擊郵件連結 → 驗 token → 將 Users.is_verified=true
  • POST /login:登入(要 is_verified=true 才放行)
  • POST /forgot-password:輸入 email → 建 RESET token,寄重設信
  • POST /reset-password:帶 token、new_password 重設

Register

  • 前端送 /register(username/email/password)
  • Lambda 建 Users、塞 hash、is_verified=false
  • Lambda 生成 VERIFY token → 寫 AuthTokens(TTL 例如 24h)
  • Lambda 用 SES 寄信:https://<api>/verify?token=<uuid>
  • 使用者點連結 → /verify → 成功 → 回前端顯示「已啟用」

Forgot/Reset

  • 前端送 /forgot-password(email)
  • Lambda 查 Users by GSI1,如果存在 → 產 RESET token → 寫 AuthTokens(TTL 例如 30 分)→ 寄信:https://app/reset.html?token=...
  • reset.html 讀 URL 中 token,輸入新密碼 → POST /reset-password(token, new_password)
  • Lambda 驗 token、更新 Users.password_hash/salt、將 token used=true

上一篇
【Day 19】 以 MediaConvert 實現一鍵轉檔功能
下一篇
【Day 21】 會員功能擴充 - 設定寄信重設密碼功能 (下)
系列文
無法成為片師也想拍 Vlog?!個人影音小工具的誕生!24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言